home *** CD-ROM | disk | FTP | other *** search
- const
- _active_voice = $102;
- _command = $103;
- _data_low = $104;
- _data_high = $105;
- _dram_io = $107;
-
- active_voice : word = _active_voice;
- command : word = _command;
- data_low : word = _data_low;
- data_high : word = _data_high;
- dram_io : word = _dram_io;
- gus_info : array[0..7] of byte = ($42,$45,$54,$41,$2f,$41,$44,$4e);
-
- {$s-}
- Procedure GUSDelay; Assembler;
- ASM
- mov dx,base
- add dx,$100
- in al, dx
- in al, dx
- in al, dx
- in al, dx
- in al, dx
- in al, dx
- in al, dx
- End;
-
- Function VoicePos( V : Byte) : Longint;
- Var
- P : Longint;
- I, Temp0, Temp1 : Word;
- Begin
- Port [active_voice] := V;
- Port [command] := $8A;
- Temp0 := Portw[data_low];
- Port [command] := $8B;
- Temp1 := Portw[data_low];
- VoicePos := (Temp0 SHL 7)+ (Temp1 SHR 8);
- End;
-
-
- Function GUSPeek(Loc : Longint) : Byte;
- Var
- B : Byte;
- AddLo : Word;
- AddHi : Byte;
- Begin
- AddLo := Loc AND $FFFF;
- AddHi := LongInt(Loc AND $FF0000) SHR 16;
-
- Port [base+$103] := $43;
- Portw[base+$104] := AddLo;
- Port [base+$103] := $44;
- Port [base+$105] := AddHi;
-
- B := Port[base+$107];
- GUSPeek := B;
- End;
-
-
- Procedure GUSPoke(Loc : Longint; B : Byte);
- Var
- AddLo : Word;
- AddHi : Byte;
- Begin
- AddLo := Loc AND $FFFF;
- AddHi := longint(Loc and $ff0000) shr 16;
- Port [Base+$103] := $43;
- Portw[Base+$104] := AddLo;
- Port [Base+$103] := $44;
- Port [Base+$105] := AddHi;
- Port [Base+$107] := B;
- End;
-
-
- Function GUSProbe(adr : word) : Boolean;
- Var
- B: Byte;
- obase : word;
- Begin
- obase := base;
- base := adr;
- Port [base+$103] := $4C;
- Port [base+$105] := 0;
- GUSDelay;
- GUSDelay;
- Port [base+$103] := $4C;
- Port [base+$105] := 1;
- GUSPoke(0, $AA);
- GUSPoke($100, $55);
- B := GUSPeek(0);
- base := obase;
- If B = $AA then GUSProbe := True else GUSProbe := False;
- End;
-
-
- Procedure GUSFind;
- Var
- I : Word;
- b : word;
- Begin
- if base = $200 then begin
- i := 1;
- while i < 8 do begin
- B := $200 + I*$10;
- If GUSProbe(b) then I := 8;
- inc(i);
- End;
- if b < $280 then base := b
- else base := $200;
- end;
- if base <> $200 then begin
- active_voice := base+_active_voice;
- command := base+_command;
- data_low := base+_data_low;
- data_high := base+_data_high;
- dram_io := base+_dram_io;
- end;
- End;
-
-
- Function GUSFindMem : Longint;
- { Returns how much RAM is available on the GUS }
- Var
- I : Longint;
- B : Byte;
- Begin
- GUSPoke($40000, $AA);
- If GUSPeek($40000) <> $AA then I := $3FFFF
- else
- Begin
- GUSPoke($80000, $AA);
- If GUSPeek($80000) <> $AA then I := $8FFFF
- else
- Begin
- GUSPoke($C0000, $AA);
- If GUSPeek($C0000) <> $AA then I := $CFFFF
- else I := $FFFFF;
- End;
- End;
- guspoke(0,$aa);
- if guspeek(0) <> $aa then i := 0;
- GUSFindMem := I;
- End;
-
- Procedure GUSSetFreq( V : Byte; hz : Word); assembler;
- asm
- cli
- mov dx,active_voice
- mov al,v
- out dx,al
- mov dx,command
- mov al,1
- out dx,al
- mov dx,data_low
- mov ax,hz
- out dx,ax
-
- {Port [Base+$102] := V;
- Port [Base+$103] := 1;
- Portw[Base+$104] := hz;}
- sti
- end;
-
- Procedure GUSVoiceControl( V, B : Byte);
- Begin
- asm cli end;
- Port [Base+$102] := V;
- Port [Base+$102] := V;
- Port [Base+$102] := V;
- Port [Base+$103] := $0;
- Port [Base+$105] := B;
- asm sti end;
- End;
-
- Procedure GUSSetBalance( V, Bal : Byte);
- Begin
- asm cli
-
- mov dx,active_voice
- mov al,v
- out dx,al
- mov dx,command
- mov al,0ch
- out dx,al
- mov dx,data_high
- mov al,bal
- out dx,al
-
- {Port [active_voice] := V;
- Port [command] := $C;
- Port [data_high] := Bal;}
- sti
- end;
- End;
-
- Procedure GUSSetVolume( V : Byte; Vol : Word); assembler;
- asm
- cli
- mov dx,active_voice
- mov al,v
- out dx,al
- mov dx,command
- mov al,9
- out dx,al
- mov dx,data_low
- mov ax,vol
- out dx,ax
- {Port [Base+$102] := V;
- Port [Base+$103] := 9;
- Portw[Base+$104] := Vol;} { 0-0ffffh, log ... not linear }
- sti
- End;
-
- Procedure GUSSetLoopMode( V : Byte);
- Var
- Temp : Byte;
- Begin
- asm cli end;
- Port [Base+$102] := V;
- Port [Base+$102] := V;
- Port [Base+$102] := V;
- Port [Base+$103] := $80;
- Temp := Port[Base+$105];
- Port [Base+$103] := 0;
- Port [Base+$105] := (Temp AND $E7) OR 0;
- asm sti end;
- End;
-
- Procedure GUSStopVoice( V : Byte);
- Var
- Temp : Byte;
- Begin
- asm cli end;
- Port [active_voice] := V;
- Port [active_voice] := V;
- Port [command] := $80;
- Temp := Port[data_high];
- Port [command] := 0;
- Port [data_high] := (Temp AND $df) OR 3;
- GUSDelay;
- Port [command] := 0;
- Port [data_high] := (Temp AND $df) OR 3;
- asm sti end;
- gussetvolume(v,0);
- End;
-
-
- Procedure GUSPlayVoice( V, Mode : Byte;VBegin, VStart, VEnd : Longint);
- Begin
- asm cli end;
- Port [active_voice] := V;
- Port [active_voice] := V;
- port [command] := 0;
- port [data_high] := 2; {stop voice}
-
- Port [command] := $0A;
- Portw[data_low] := (VBegin SHR 7) AND 8191;
- Port [command] := $0B;
- Portw[data_low] := (VBegin AND 127) SHL 9;
- Port [command] := $02;
- Portw[data_low] := (VStart SHR 7) AND 8191;
- Port [command] := $03;
- Portw[data_low] := (VStart AND 127) SHL 9;
- Port [command] := $04;
- Portw[data_low] := ((VEnd) SHR 7) AND 8191;
- Port [command] := $05;
- Portw[data_low] := ((VEnd) AND 127) SHL 9;
-
- Port [command] := $0;
- Port [data_high] := Mode and $fe;
- asm sti end;
- end;
-
- Procedure GUSPlayAll( V, Mode : Byte;VBegin, VStart, VEnd : Longint;
- freq,vol : word);
- Begin
- asm cli end;
- asm
- mov dx,active_voice {Port [active_voice] := V;}
- mov al,v
- out dx,al
- mov cx,command {port [command] := 0;}
- mov dx,cx
- mov al,0
- out dx,al
- mov dx,data_high {port [data_high] := 2;} {stop voice}
- mov al,2
- out dx,al
- mov dx,cx
- mov al,9
- out dx,al {port [command] := 9;}
- mov dx,data_low
- mov ax,vol
- out dx,ax {portw[data_low] := vol;} {set volume}
-
- mov dx,cx
- mov al,1
- out dx,al {port [command] := 1;}
- mov dx,data_low
- mov ax,freq
- out dx,ax {portw[data_low] := freq;}
- end;
- Port [command] := $0A;
- Portw[data_low] := (VBegin SHR 7) AND 8191;
- Port [command] := $0B;
- Portw[data_low] := (VBegin AND 127) SHL 9;
- Port [command] := $02;
- Portw[data_low] := (VStart SHR 7) AND 8191;
- Port [command] := $03;
- Portw[data_low] := (VStart AND 127) SHL 9;
- Port [command] := $04;
- Portw[data_low] := ((VEnd) SHR 7) AND 8191;
- Port [command] := $05;
- Portw[data_low] := ((VEnd) AND 127) SHL 9;
-
- Port [command] := $0;
- Port [data_high] := Mode and $fe;
- asm sti end;
- end;
-
- procedure gusrelvoice(v : byte);
- var
- b : byte;
- begin
- port[active_voice] := v;
- port[command] := $80;
- b := port[data_high];
- port[command] := 0;
- port[data_high] := b and $fc;
- end;
-
- procedure gusrelvoices(n : byte); assembler;
- asm
- mov bl,n
- @@1:
- mov dx,base
- add dx,102h
- mov al,bl
- out dx,al
- inc dx
- mov al,80h
- out dx,al
- add dx,2
- in al,dx
- mov al,0
- sub dx,2
- out dx,al
- add dx,2
- mov cl,al
- and cl,0fdh
- mov al,cl
- out dx,al
- dec bl
- jnz @@1
- end;
-
- procedure GusSetOfs(v : byte;vbegin : longint);
- begin
- asm cli end;
- Port [active_voice] := V;
- Port [active_voice] := V;
- Port [command] := $0A;
- Portw[data_low] := (VBegin SHR 7) AND 8191;
- Port [command] := $0B;
- Portw[data_low] := (VBegin AND 127) SHL 9;
- asm sti end;
- end;
-
-
- Procedure GUSReset;
- var
- n : integer;
- Begin
- Port[Base] := 3;
- port [base+$103] := $4C;
- port [Base+$105] := 1;
- GUSDelay;
- port [base+$103] := $4c;
- port [base+$105] := 0;
- gusdelay;
- port [base+$103] := $4c;
- port[base+$105] := 1;
- gusdelay;
- port [base+$103] := $4C;
- port [Base+$105] := 7;
-
- port [base+$103] := $0E;
- port [Base+$105] := (13 OR $0C0);
-
- gusdelay;
- port[base] := 1;
- Port[base+_command] := $4C;
- Port[Base+_data_high] := 7;
- n := gus_info[1];
- for n := 1 to 14 do begin
- port[base+_active_voice] := n;
- port[base+_command] := 0;
- port[base+_data_high] := 2; {stop all voices}
- port[base+_command] := $d;
- port[base+_data_high] := 2;
- port[base+_command] := $a;
- portw[base+_data_low] := 0;
- port[base+_command] := $b;
- portw[base+_data_low] := 0;
- port[base+_command] := 9;
- portw[base+_data_low] := 0;
- end;
- End;
-
- {$s-}
-
- procedure gusdeinit;
- var
- n : word;
- begin
- for n := 1 to 14 do gusstopvoice(n);
- end;
-